package com.spzx.auth.service;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.spzx.auth.form.RegisterBody;
import com.spzx.common.core.constant.CacheConstants;
import com.spzx.common.core.constant.Constants;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.constant.UserConstants;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.enums.UserStatus;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.common.core.text.Convert;
import com.spzx.common.core.utils.StringUtils;
import com.spzx.common.core.utils.ip.IpUtils;
import com.spzx.common.redis.service.RedisService;
import com.spzx.system.api.model.LoginUser;
import com.spzx.user.api.RemoteUserInfoService;
import com.spzx.user.api.domain.UpdateUserLogin;
import com.spzx.user.api.domain.UserInfoDto;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
public class H5LoginService {

    @Autowired
    private RedisService redisService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RemoteUserInfoService remoteUserInfoService;

    @Autowired
    private SysRecordLogService recordLogService;

    @Autowired
    private SysPasswordService passwordService;

    public void register(RegisterBody registerBody) {
        BoundHashOperations<String, String, Object> hashOps = redisTemplate.boundHashOps(UserConstants.SMS_CODE + registerBody.getUsername());
        String inputCode = registerBody.getCode();
        String sendTime = String.valueOf(hashOps.get(UserConstants.HASH_KEY1));
        String smsCode = (String) hashOps.get(UserConstants.HASH_KEY3);
        String isUsed = (String) hashOps.get(UserConstants.HASH_KEY4);
        DateTime dateTime = DateUtil.parse(sendTime);
        long diffInMillies = System.currentTimeMillis() - dateTime.getTime();
        if (diffInMillies > 5 * 60 * 1000 || "1".equals(isUsed)) {
            throw new ServiceException("验证码已过期，请重新获取验证码");
        }
        if (!inputCode.equals(smsCode)) {
            throw new ServiceException("验证码输入错误，请重新输入");
        }
        UserInfoDto dto = new UserInfoDto();
        BeanUtils.copyProperties(registerBody, dto);
        R<Boolean> result = remoteUserInfoService.register(dto, SecurityConstants.INNER);
        if (StringUtils.isNull(result)) {
            throw new ServiceException("系统繁忙，请稍后再试");
        }
        if (R.FAIL == result.getCode()) {
            throw new ServiceException(result.getMsg());
        }
        hashOps.put(UserConstants.HASH_KEY4, "1");
        recordLogService.recordLogininfor(registerBody.getUsername(), Constants.REGISTER, "注册成功");
    }

    public LoginUser login(String username, String password) {
        // IP黑名单校验
        String blackStr = Convert.toStr(redisService.getCacheObject(CacheConstants.SYS_LOGIN_BLACKIPLIST));
        if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) {
            recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "很遗憾，访问IP已被列入系统黑名单");
            throw new ServiceException("很遗憾，访问IP已被列入系统黑名单");
        }
        // 查询用户信息
        R<UserInfoDto> userRes = remoteUserInfoService.getUserInfo(username, SecurityConstants.INNER);
        if (StringUtils.isNull(userRes.getData())) {
            recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "登录用户不存在");
            throw new ServiceException("登录用户：" + username + " 不存在");
        }
        if (R.FAIL == userRes.getCode()) {
            throw new ServiceException(userRes.getMsg());
        }
        UserInfoDto userInfo = userRes.getData();
        LoginUser loginUser = new LoginUser();
        loginUser.setUserid(userInfo.getId());
        loginUser.setUsername(userInfo.getUsername());
        loginUser.setPassword(userInfo.getPassword());
        loginUser.setStatus(userInfo.getStatus() + "");
        if (UserStatus.DISABLE.getCode().equals(userInfo.getStatus())) {
            recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户已停用，请联系管理员");
            throw new ServiceException("对不起，您的账号：" + username + " 已停用");
        }
        passwordService.validate(loginUser, password);
        recordLogService.recordLogininfor(username, Constants.LOGIN_SUCCESS, "登录成功");
        //更新登录信息
        UpdateUserLogin updateUserLogin = new UpdateUserLogin();
        updateUserLogin.setUserId(userInfo.getId());
        updateUserLogin.setLastLoginIp(IpUtils.getIpAddr());
        updateUserLogin.setLastLoginTime(new Date());
        remoteUserInfoService.updateUserLogin(updateUserLogin, SecurityConstants.INNER);
        return loginUser;
    }
}
